package com.it.service.impl;


import java.util.UUID;
import com.alipay.api.AlipayApiException;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.it.aiInsureOrder.OrderApi;
import com.it.config.AlipayConfig;
import com.it.entity.aiClaimRegistration.AiClaimRegistration;
import com.it.entity.insure.AiInsureOrder;
import com.it.entity.pay.AiPay;
import com.it.mapper.AiPayMapper;
import com.it.service.AiPayService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import utils.R;
import utils.ResultCodeEnum;
import com.alibaba.fastjson.JSONObject;


import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service
public class AiPayServiceImpl extends ServiceImpl<AiPayMapper, AiPay> implements AiPayService {
    private static final String ALIPAY_SANDBOX_GATEWAY = "https://openapi-sandbox.dl.alipaydev.com/gateway.do";
    private static final String CHARSET = "UTF-8";
    private static final String FORMAT = "JSON";
    private static final String SIGN_TYPE = "RSA2";
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");

    @Resource
    private AlipayConfig alipayConfig; // 支付宝配置（appId、密钥等）


    @Autowired
    private AiPayMapper aiPayMapper;
    @Resource
    private OrderApi orderApi;
    @Override
    public R getAiPayList(int pageNum, int pageSize, String policyId, Integer paymentStatus) {
        PageHelper.startPage(pageNum, pageSize);
        LambdaQueryWrapper<AiPay> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(policyId)) {
            queryWrapper.eq(AiPay::getPolicyId,policyId);
        }
        if (paymentStatus != null) {
            queryWrapper.eq(AiPay::getPaymentStatus,paymentStatus);
        }
        List<AiPay> aiPays = aiPayMapper.selectList(queryWrapper);
        return R.Success("查询成功",new PageInfo<>(aiPays));
    }


    @Override
    public String createPayRecord(String policyId, String paymentAmount) {
        try {
            if (policyId == null || policyId.trim().isEmpty()) {
                return null;
            }
            if (paymentAmount == null || !paymentAmount.matches("^\\d+(\\.\\d{1,2})?$")) {
                return null;
            }
            BigDecimal payAmount;
            try {
                payAmount = new BigDecimal(paymentAmount);
            } catch (NumberFormatException e) {
                return null;
            }
            if (payAmount.compareTo(BigDecimal.ZERO) <= 0) {
                return null;
            }
            String paymentId = "ALIPAY" + LocalDateTime.now().format(DATE_FORMATTER)
                    + UUID.randomUUID().toString().replace("-", "").substring(0, 6);
            String subject = "农业保险保费支付（保单号：" + policyId + "）";

            AiPay aiPay = new AiPay()
                    .setPaymentId(paymentId)          // 支付记录ID
                    .setPolicyId(policyId)            // 关联保单号
                    .setPaymentAmount(payAmount)      // 支付金额
                    .setPaymentStatus(1)              // 状态：1-待支付
                    .setSubject(subject)              // 订单标题
                    .setPaymentRemark("前端发起待支付记录") // 备注
                    .setUpdateTime(LocalDateTime.now()); // 更新时间
            aiPayMapper.insert(aiPay);
            Map<String, String> resultData = new HashMap<>();
            resultData.put("paymentId", paymentId);       // 支付记录ID（用于后续支付）
            resultData.put("policyId", policyId);         // 保单号（回显）
            resultData.put("paymentAmount", paymentAmount); // 应付金额（回显）
            return paymentId;

        } catch (Exception e) {
            // 捕获异常，返回系统异常响应
            e.printStackTrace();
            return "创建待支付记录异常：" ;
        }
    }

    /**
     * 生成支付宝支付表单（对接支付宝SDK）
     */
    @Override
    public String generateAlipayForm(String paymentId, String returnUrl) {
        try {
            AiPay aiPay = this.getById(paymentId);
            // 校验记录存在
            if (aiPay == null) {
                return "<html><body><h3 style='color:#f56c6c'>未找到支付记录，paymentId：" + paymentId + "</h3></body></html>";
            }
            // 校验状态为“待支付”
            if (aiPay.getPaymentStatus() == 2) {
                return "<html><body><h3 style='color:#f56c6c'>订单已支付成功，无法重复发起支付</h3></body></html>";
            }

            DefaultAlipayClient alipayClient = new DefaultAlipayClient(
                    ALIPAY_SANDBOX_GATEWAY,
                    alipayConfig.getAppId(),
                    alipayConfig.getAppPrivateKey(),
                    FORMAT,
                    CHARSET,
                    alipayConfig.getAlipayPublicKey(),
                    SIGN_TYPE
            );

            AlipayTradePagePayRequest payRequest = new AlipayTradePagePayRequest();
            // 异步通知地址（从配置读取，需公网可访问）
            payRequest.setNotifyUrl(alipayConfig.getNotifyUrl());
            // 同步跳转地址（前端页面）
            payRequest.setReturnUrl(returnUrl);
            // 组装业务参数（JSON格式）
            JSONObject bizContent = new JSONObject();
            bizContent.put("out_trade_no", aiPay.getPaymentId());  //  交易订单号
            bizContent.put("total_amount", aiPay.getPaymentAmount());// 支付金额
            bizContent.put("subject", aiPay.getSubject());          // 订单标题
            bizContent.put("body", "保单号：" + aiPay.getPolicyId());// 订单描述
            bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");// 支付宝产品码
            payRequest.setBizContent(bizContent.toJSONString());
            AiInsureOrder aiInsureOrder = new AiInsureOrder();

            return alipayClient.pageExecute(payRequest).getBody();

        } catch (AlipayApiException e) {
            // 支付宝SDK异常（如密钥错误、参数错误）
            e.printStackTrace();
            return "<html><body><h3 style='color:#f56c6c'>发起支付失败：" + e.getErrMsg() + "</h3></body></html>";
        } catch (Exception e) {
            // 其他系统异常
            e.printStackTrace();
            return "<html><body><h3 style='color:#f56c6c'>发起支付异常：" + e.getMessage() + "</h3></body></html>";
        }
    }

    @Override
    public String handleAlipayNotify(HttpServletRequest request) {
        try {
            Map<String, String> paramMap = new HashMap<>();
            Map<String, String[]> requestParams = request.getParameterMap();
            for (String paramName : requestParams.keySet()) {
                paramMap.put(paramName, request.getParameter(paramName));
            }
            // 提取核心参数
            String tradeStatus = paramMap.get("trade_status");
            String PaymentId = paramMap.get("out_trade_no");
            String alipayTradeNo = paramMap.get("trade_no");
            String buyerId = paramMap.get("buyer_id");
            String gmtPayment = paramMap.get("gmt_payment");
            String gmtClose = paramMap.get("gmt_close");
            String sign = paramMap.get("sign");

            if (tradeStatus == null || PaymentId == null || sign == null) {
                System.out.println("支付宝回调参数缺失：tradeStatus=" + tradeStatus + "，outTradeNo=" + PaymentId);
                return "fail";
            }
            boolean isSignValid = AlipaySignature.rsa256CheckContent(
                    AlipaySignature.getSignCheckContentV1(paramMap),
                    sign,
                    alipayConfig.getAlipayPublicKey(),
                    CHARSET
            );
            if (!isSignValid) {
                System.out.println("支付宝回调验签失败，PaymentId：" + PaymentId);
                return "fail";
            }
            AiPay aiPay = this.lambdaQuery()
                    .eq(AiPay::getPaymentId, PaymentId)
                    .one();
            if (aiPay == null) {
                System.out.println("支付宝回调：未找到支付记录，PaymentId：" + PaymentId);
                return "fail";
            }
            // 校验状态为“待支付”（避免重复处理）
            if (aiPay.getPaymentStatus() != 1) {
                System.out.println("支付宝回调：支付记录已处理，PaymentId：" + aiPay.getPaymentId());
                return "success";
            }
            LocalDateTime now = LocalDateTime.now();
            if ("TRADE_SUCCESS".equals(tradeStatus)) {
                // 支付成功：更新状态为2，补充支付宝字段
                aiPay.setPaymentStatus(2)
                        .setAlipaySandboxTradeNo(alipayTradeNo)
                        .setAlipaySandboxUserId(buyerId)
                        .setPaymentTime(LocalDateTime.parse(gmtPayment, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
                        .setPaymentRemark("支付宝沙箱支付成功，交易号：" + alipayTradeNo)
                        .setUpdateTime(now);
                // 同步更新保单状态为“已缴费”（调用保单Service）
                AiInsureOrder aiInsureOrder = new AiInsureOrder()
                        .setPolicyId(aiPay.getPolicyId())
                        .setPayStatus(3)
                        .setPolicyStatus(2);
                orderApi.updateStatus(aiInsureOrder);

            } else if ("TRADE_CLOSED".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)) {
                // 支付失败/关闭：更新状态为3
                aiPay.setPaymentStatus(3)
                        .setPaymentRemark("支付宝交易" + (tradeStatus.equals("TRADE_CLOSED") ? "关闭" : "结束")
                                + "，关闭时间：" + gmtClose)
                        .setUpdateTime(now);
                // 同步更新保单状态为“待缴费”
                AiInsureOrder aiInsureOrder = new AiInsureOrder()
                        .setPolicyId(aiPay.getPolicyId())
                        .setPayStatus(1)
                        .setPolicyStatus(4);
                orderApi.updateStatus(aiInsureOrder);

            } else {
                // 其他状态（如TRADE_PENDING）暂不处理
                System.out.println("支付宝回调：未处理状态，tradeStatus：" + tradeStatus);
                return "success";
            }
            boolean updateSuccess = this.updateById(aiPay);
            if (updateSuccess) {
                System.out.println("支付宝回调：支付记录更新成功，paymentId：" + aiPay.getPaymentId());
                return "success";
            } else {
                System.out.println("支付宝回调：支付记录更新失败，paymentId：" + aiPay.getPaymentId());
                return "fail";
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("支付宝回调处理异常：" + e.getMessage());
            return "fail";
        }
    }
}
